package provider_consumer;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

public class Test2 {

    @org.junit.Test
    public void test1() {
        FoodBox foodBox = new FoodBox();
        for (int i = 0; i < 10; i++) {
            Consumer consumer = new Consumer();
            consumer.setFoodBox(foodBox);
            new Thread(() -> {
                while (true) {
                    consumer.eat();
                }
            }).start();


        }
        for (int i = 0; i < 5; i++) {
            Producer producer = new Producer();
            producer.setFoodBox(foodBox);
            new Thread(() -> {
                while (true) {
                    producer.put();
                }
            }).start();
        }

        while (true) {

        }

    }

    class Producer {
        private FoodBox foodBox;

        public FoodBox getFoodBox() {
            return foodBox;
        }

        public void setFoodBox(FoodBox foodBox) {
            this.foodBox = foodBox;
        }

        public void put() {

            this.foodBox.add(new Food(foodBox.foodList.size() + 1));
        }
    }

    class Consumer {
        private FoodBox foodBox;

        public void eat() {
            this.foodBox.remove();

        }

        public FoodBox getFoodBox() {
            return foodBox;
        }

        public void setFoodBox(FoodBox foodBox) {
            this.foodBox = foodBox;
        }
    }

    class Food {
        public int id;

        public Food(int id) {
            this.id = id;
        }
    }

    class FoodBox {
        public ReentrantLock lock = new ReentrantLock();
        Condition consumer = lock.newCondition();
        Condition producer = lock.newCondition();
        private List<Food> foodList = new ArrayList<>();
        private int maxSize = 10;

        public void add(Food food) {
            lock.lock();
            try {
                while (foodList.size() == maxSize) {
                    System.out.println("食物满了，等人吃一点。。");
                    producer.await();
                    System.out.println("又可以造食物了。。");
                }
                consumer.signalAll();
                foodList.add(food);
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                lock.unlock();
            }


        }

        public Food remove() {
            lock.lock();
            try {
                while (foodList.size() == 0) {
                    System.out.println("食物空了，等人造一点。。");
                    consumer.await();
                    System.out.println("食物有了，可以吃了。。");
                }
                producer.signalAll();
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                lock.unlock();
            }
            return foodList.remove(0);
        }
    }

}
